﻿Public Module World
    Public Time As Time

    Public mapRS As TVRenderSurface
    '48,24 x=1152
    Public MapSize As Integer = 15
    Public MapSizePx As Integer = (MapSize + 1) * 16
    Public Map(MapSize, MapSize) As Byte 'Map weight.
    Public Tile(MapSize, MapSize) As Integer 'Map textures.

    Public TileTex() As Integer

    Public Homes(2) As Home.Home

    Public NPCs As New List(Of NPC)

    Public Sub World_Load()
        Time = New Time(1220, 1, 1, 19, 0)

        'Create the render surface for the tiles.
        mapRS = Scene.CreateRenderSurface(MapSizePx, MapSizePx)


        'Load all of the land textures.
        Dim Files() As String = IO.Directory.GetFiles("Data\Land\", "*.dds")
        ReDim TileTex(Files.Length - 1)
        For n As Integer = 0 To Files.Length - 1
            TileTex(n) = Tex.LoadTexture(Files(n), IO.Path.GetFileNameWithoutExtension(Files(n)))
        Next

        'Create the base of the homes.
        Homes(0) = New Home.Home
        Homes(1) = New Home.Home
        Homes(2) = New Home.Home
    End Sub

    Public Sub World_Render()
        mapRS.StartRender()
        Scr2D.Action_Begin2D()
        Scr2D.Draw_FilledBox(0, 0, MapSizePx, MapSizePx, RGBA(0.2, 0.2, 0.2, 1))

        'Loop thru each tile.
        For x As Short = 0 To MapSize
            For y As Short = 0 To MapSize
                'Convert the grid positoin to the real position.
                Dim x2 As Short = x * 16
                Dim y2 As Short = y * 16
                'Draw the tile.
                Scr2D.Draw_Texture(Tile(x, y), x2, y2, x2 + 15, y2 + 15)
            Next
        Next


        Scr2D.Action_End2D()
        mapRS.EndRender()
    End Sub

    Public Sub Render_NPC()
        For Each NPC As NPC In NPCs
            NPC.Render()
        Next
    End Sub


    Public Sub World_Tick()
        Time.Tick()

        'Update the npcs.
        For Each NPC As NPC In NPCs
            NPC.Tick()
        Next
    End Sub


    Public Function TileToString() As String
        Dim tmp As String = Tile(0, 0)
        For x As Short = 0 To MapSize
            For y As Short = 0 To MapSize
                If x = 0 And y = 0 Then
                Else
                    tmp &= "," & Tile(x, y)
                End If
            Next
        Next
        Return tmp
    End Function
    Public Function MapToString() As String
        Dim tmp As String = Map(0, 0)
        For x As Short = 0 To MapSize
            For y As Short = 0 To MapSize
                If x = 0 And y = 0 Then
                Else
                    tmp &= "," & Map(x, y)
                End If
            Next
        Next
        Return tmp
    End Function
    Public Sub FromString(ByVal nMap() As String, ByVal nTile() As String)
        Dim num As Integer = 0
        For x As Integer = 0 To MapSize
            For y As Integer = 0 To MapSize
                If num < nMap.Length Then
                    Map(x, y) = nMap(num)
                Else
                    Map(x, y) = 10
                End If
                If num < nTile.Length Then
                    Tile(x, y) = nTile(num)
                Else
                    Tile(x, y) = TileTex(0)
                End If
                num += 1
            Next
        Next
    End Sub


    Public Sub SaveMap()
        Dim sd As New SimpleD.Group()

        Dim g As SimpleD.Group = sd.CreateGroup("Map")
        g.SetValue("Time", Time.ToString(True))
        g.SetValue("Size", MapSize)
        g.SetValue("Tile", TileToString)
        g.SetValue("Map", MapToString)

        g.SetValue("Homes", Homes.Length)

        For h As Integer = 0 To Homes.Length - 1
            g.SetValue("Home" & h, Homes(h).ToString)
        Next

        sd.ToFile("Data\Maps\Test.sd")
    End Sub

    Public Sub OpenMap()
        Dim sd As New SimpleD.Group("Data\Maps\Test.sd", True)
        Dim g As SimpleD.Group = sd.GetGroup("map")

        Time.FromString(g.GetValue("Time"))

        Dim tmpSize As Integer = RoundP2(g.GetValue("size"))
        If tmpSize <> MapSize Then
            MapSize = tmpSize - 1
            MapSizePx = (tmpSize) * 16
            ReDim Map(MapSize, MapSize)
            ReDim Tile(MapSize, MapSize)
            mapRS.Destroy()
            mapRS = Scene.CreateRenderSurface(MapSizePx, MapSizePx)
        End If

        FromString(Split(g.GetValue("map"), ","), Split(g.GetValue("tile"), ","))

        For h As Integer = 0 To Homes.Length - 1
            Homes(h).FromString(Split(g.GetValue("home" & h), ","))
        Next

        World_Render()
    End Sub

    Public Function RoundP2(ByVal v As UInteger)
        v -= 1
        v = v Or v >> 1
        v = v Or v >> 2
        v = v Or v >> 4
        v = v Or v >> 8
        v = v Or v >> 16
        'v += 1
        Return v + 1
    End Function

End Module

Public Structure TexturePack
    Public Texture As Integer
    Public Textures As List(Of String)
End Structure

Public Class Time
    Public Year, Month, Day, Hour As Short
    Public Minute As Single
    Public TimeElasped As Single

    Public Sub New(ByVal Year As Short, ByVal Month As Short, ByVal Day As Short, ByVal Hour As Short, ByVal Minute As Short)
        Me.Year = Year
        Me.Month = Month
        Me.Day = Day

        Me.Hour = Hour
        Me.Minute = Minute
    End Sub

    Public Sub Tick()
        TimeElasped = TV.AccurateTimeElapsed * 0.001

        Minute += TimeElasped
        If Minute >= 60 Then
            Minute = 0

            Hour += 1
            If Hour > 23 Then
                Hour = 0

                Day += 1
                If Day > 30 Then
                    Day = 1

                    Month += 1
                    If Month > 12 Then
                        Month = 1
                        Year += 1
                    End If
                End If
            End If
        End If
    End Sub

    Public Overrides Function ToString() As String
        Return Year & ", " & Month & ", " & Day & vbNewLine & Hour & ":" & System.Math.Round(Minute)
    End Function
    Public Overloads Function ToString(ByVal UseForData As Boolean) As String
        Return Year & "," & Month & "," & Day & "," & Hour & "," & System.Math.Round(Minute)
    End Function
    Public Sub FromString(ByVal str As String)
        Dim Data() As String = Split(str, ",")
        If Data.Length < 5 Then Return
        Year = Data(0)
        Month = Data(1)
        Day = Data(2)
        Hour = Data(3)
        Minute = Data(4)
    End Sub
End Class